import {Promise} from 'es6-promise';
import PWSApp from "../../core/app";
import HomeBaseAction from "./act.base";
import {Magics} from "../../core/magics";
import {Request, Response} from "express";
import * as utils from '../../core/utils';
import {RouteType} from "../../core/defines";
import {ErrCode} from "../../core/error.code";
import {MongoColls} from "../../config/mongo";
import AddressModel, {
    AddressInfo,
    AddrStatus,
} from "../../models/mod.address";
import {ObjectID} from "mongodb";

export default class AddrAction extends HomeBaseAction {

    name() {
        return `${this.app.name}AddrAction`;
    }

    private _addrMod:AddressModel;

    constructor(app:PWSApp) {
        super(app);
        this._addrMod = new AddressModel(this.db.collection(MongoColls.ADDRESS));
    }

    protected _setRoutes() {
        this._setRoot('/api/addr'); //need login
        this._route(RouteType.POST, '/create', this._actAddrCreate);
        this._route(RouteType.GET, '/detail', this._actAddrDetail);
        this._route(RouteType.GET, '/list', this._actAddrList);
        this._route(RouteType.POST, '/update', this._actAddrUpdate);
        this._route(RouteType.POST, '/delete', this._actAddrDelete);
        this._route(RouteType.POST, '/default', this._actAddrDefault);
    }

    private _actAddrCreate(req:Request, res:Response) {
        Promise.resolve().then(() => {
            let {name, phone, loc, address} = req.body;
            if (!name || !utils.isPhone(phone) || !utils.isObject(loc) || !address) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            let sessUser = req.session[Magics.SessUser] || {};
            let userAddr = {
                name, phone, address,
                user_id: utils.toObjectId(sessUser['_id']),
                loc: {
                    prov: loc.prov || '',
                    city: loc.city || '',
                    dist: loc.dist || ''
                },
                time: new Date(),
                status: AddrStatus.NONE
            };
            return this._addrMod.newAddress(userAddr);
        }).then(() => {
            res.send({err_code: ErrCode.Success});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actAddrDetail(req:Request, res:Response) {
        let {addr_id} = req.query;
        Promise.resolve().then(() => {
            if (!utils.isObjectId(addr_id)) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            return this._addrMod.checkExist({addrId: utils.toObjectId(addr_id)});
        }).then((data) => {
            res.send({
                addr: data || {},
                err_code: ErrCode.Success,
            });
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actAddrList(req:Request, res:Response) {
        Promise.resolve().then(() => {
            let sessUser = req.session[Magics.SessUser] || {};
            if (!utils.isObjectId(sessUser['_id'])) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            let userId = utils.toObjectId(sessUser['_id']);
            return this._addrMod.getAddressList({userId: userId});
        }).then((data) => {
            res.send({err_code: ErrCode.Success, addrs: data});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actAddrUpdate(req:Request, res:Response) {
        let {name, phone, loc, address, addr_id} = req.body;
        Promise.resolve().then(() => {
            let invalid = !name || !utils.isPhone(phone) || !utils.isObject(loc)
                || !address || !utils.isObjectId(addr_id);
            if (invalid) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            let userAddr = {
                name, phone, address,
                loc: {
                    prov: loc.prov || '',
                    city: loc.city || '',
                    dist: loc.dist || ''
                },
                time: new Date()
            };
            let filter = {addrId: utils.toObjectId(addr_id)};
            return this._addrMod.updateAddress(filter, userAddr);
        }).then(() => {
            res.send({err_code: ErrCode.Success});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actAddrDelete(req:Request, res:Response) {
        let {addr_id} = req.body;
        Promise.resolve().then(() => {
            if (!utils.isObjectId(addr_id)) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            let addrId:ObjectID = utils.toObjectId(addr_id);
            return this._addrMod.delAddress({addrId});
        }).then(() => {
            res.send({err_code: ErrCode.Success});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actAddrDefault(req:Request, res:Response) {
        Promise.resolve().then(() => {
            let {addr_id} = req.body;
            let sessUser = req.session[Magics.SessUser] || {};
            if (!utils.isObjectId(addr_id) || !utils.isObjectId(sessUser['_id'])) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }

            let addrId:ObjectID = utils.toObjectId(addr_id);
            let userId:ObjectID = utils.toObjectId(sessUser['_id']);
            return this._addrMod.setDefault({userId, addrId});
        }).then(() => {
            res.send({err_code: ErrCode.Success});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

}